import time
import os
import configparser
import sys
from urllib import parse, request
from multiprocessing import Pool, cpu_count

from Utility import hard
from Utility import system
from Utility import security_swxlbjs
from Utility import Authentication
from Utility import IDcard

def Register(PubPath, PriPath):
    """生成公私钥"""
    SRsaSA = security_swxlbjs.SRsa()
    PubLocal, PriLocal = SRsaSA.new(4096)
    """初始化加密,由自身ip和name生成Key"""
    SAesS = security_swxlbjs.SAes(JM.SHost(Ident['IDcard']))
    """本地私钥保存"""
    prifile = open(PriPath, 'w')
    pri = JM.Encryption(PriLocal)
    pri = SAesS.Encryption(pri)
    prifile.write(pri)
    prifile.close()
    """本地公钥加密"""
    pub = JM.Encryption(PubLocal)
    pub = SAesS.Encryption(pub)
    """传输本地公钥"""
    textmod = dict()
    textmod.update(Ident)
    textmod.update({"Key": pub})
    textmod = parse.urlencode(textmod).encode('utf-8')
    header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko', }
    req = request.Request(conf.get("API", str(sys._getframe().f_code.co_name).lower()), textmod, headers=header_dict)
    req = request.urlopen(req)
    """保存平台公钥"""
    SRsaS = security_swxlbjs.SRsa(priOutside=PriLocal)
    pub = str(req.read(), encoding='utf-8')
    pub = SAesS.Decryption(pub)
    pub = SRsaS.Decryption(pub)
    pub = SAesS.Encryption(pub)
    pubfile = open(PubPath, 'w')
    pubfile.write(pub)
    pubfile.close()

def Monitor():
    try:
        """通用方法"""
        result = []
        P = Pool(cpu_count() * 8)
        """##############################################################################################################"""
        """硬件"""
        Hard_S = hard.ClassMain()
        """网卡流量"""
        result.append(P.apply_async(Hard_S.NetInfo, callback = callable))
        """CPU运行百分比"""
        result.append(P.apply_async(Hard_S.CpuInfo, callback = callable))
        """内存使用百分比"""
        result.append(P.apply_async(Hard_S.MemInfo, callback = callable))
        """磁盘空间百分比"""
        result.append(P.apply_async(Hard_S.DiskInfo, callback = callable))
        """##############################################################################################################"""
        """系统"""
        System_S = system.ClassMain()
        """在线用户"""
        result.append(P.apply_async(System_S.UserOnline, callback = callable))
        """所有进程"""
        result.append(P.apply_async(System_S.Program, callback = callable))
        """端口状态"""
        result.append(P.apply_async(System_S.SocketConnections, callback = callable))
        """##############################################################################################################"""
        """特殊方法"""
        """获取系统所有进程"""
        System_S = system.ClassMain()
        Program = System_S.Program()['Program']
        Listen = set([(x['LocalAddress'][1], x['ProgramID']) for x in System_S.SocketConnections()['SocketConnections'] if x['Status'] == 'LISTEN'])
        """按ProgramName识别程序名"""
        for x in Program:
            if x['ProgramName'] == 'redis-server':
                Port = list(filter(lambda xx: xx[1] == x['ProgramID'], Listen))[0][0]
                Auth = Authentication.Authentication(Ident, x['ProgramName'], Port, PubKey, PriKey, conf.get("API", "authentication"))
                from Utility import Mredis
                result.append(P.apply_async(Mredis.Run, args=(Auth, Port, )))
            elif x['ProgramName'] == 'mysqld':
                Port = list(filter(lambda xx: xx[1] == x['ProgramID'], Listen))[0][0]
                Auth = Authentication.Authentication(Ident, x['ProgramName'], Port, PubKey, PriKey, conf.get("API", "authentication"))
                from Utility import Mmysql
                result.append(P.apply_async(Mmysql.Run, args=(Auth, Port, )))
        P.close()
        P.join()
        """##############################################################################################################"""
        """数据合并,加密"""
        SAesS = security_swxlbjs.SAes(JM.SHost(Ident['IDcard']))
        Data = dict()
        for x in result:
            Data.update(x.get())
        Data = {sys._getframe().f_code.co_name: SAesS.Encryption(JM.Encryption(str(Data)))}
    except:
        Data = {sys._getframe().f_code.co_name: None}
    finally:
        try:
            Data.update(Ident)
            textmod = parse.urlencode(Data).encode('utf-8')
            header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko', }
            req = request.Request(conf.get("API", "monitor"), textmod, headers=header_dict)
            req = request.urlopen(req)
            Mresult = req.read().decode('utf-8')
        except:
            Mresult = False
        finally:
            return Mresult

if __name__ == '__main__':
    print("%s: Start"% str(time.asctime(time.localtime(time.time()))))
    print("%s: Configure" % str(time.asctime(time.localtime(time.time()))))
    JM = security_swxlbjs.Security()
    Ident = IDcard.IDcard()
    conf = configparser.ConfigParser()
    conf.read(os.path.join(os.path.join(os.getcwd(), "Conf"), "configure.ini"))
    pub = conf.get("PATH", "PubKey")
    pri = conf.get("PATH", "PriKey")
    SAesS = security_swxlbjs.SAes(JM.SHost(Ident['IDcard']))
    while os.path.exists(pub) is False and os.path.exists(pri) is False:
        print("%s: Register" % str(time.asctime(time.localtime(time.time()))))
        Register(pub, pri)
        if os.path.exists(pub) is True and os.path.exists(pri) is True:
            break
    PubKey = JM.Decryption(SAesS.Decryption(open(pub).read()))
    PriKey = JM.Decryption(SAesS.Decryption(open(pri).read()))
    print("%s: Monitor Run" % str(time.asctime(time.localtime(time.time()))))
    Mresult = Monitor()
    print("%s: Monitor %s" % (str(time.asctime(time.localtime(time.time()))), Mresult))
    print("%s: End" % str(time.asctime(time.localtime(time.time()))))

